/*
 * @Author: tanjunyi@doctorwork.com
 * @Date: 2020-06-20 20:14:40
 * @LastEditors: tanjunyi@doctorwork.com
 * @LastEditTime: 2020-06-25 16:12:52
 * @Description:
 */
// Regular Expressions for parsing tags and attributes
var unicodeRegExp = /a-zA-Z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD/;
var attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
var dynamicArgAttribute = /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
var ncname = "[a-zA-Z_][\\-\\.0-9_a-zA-Z" + (unicodeRegExp.source) + "]*";
var qnameCapture = "((?:" + ncname + "\\:)?" + ncname + ")";
var startTagOpen = new RegExp(("^<" + qnameCapture));
var startTagClose = /^\s*(\/?)>/;
var endTag = new RegExp(("^<\\/" + qnameCapture + "[^>]*>"));

let root; //树根
let currentParent;
let stack = []; //用来判断标签是否闭合
function createASTElement(tagName, attrs) {
	return {
		tag: tagName,
		attrs,
		children: [],
		parent: null,
		type: 1, // 1 普通元素 3 文本
	}
}

function start(tagName, attrs) {
	let element = createASTElement(tagName, attrs);
	// TODO: 
	if (!root) {
		root = element;
	}
	currentParent = element;
	stack.push(element)
}
// 闭合标签，确立父子关系
function end(tagName) {
	let element = stack.pop();
	currentParent = stack[stack.length - 1]
	if (currentParent) {
		element.parent = currentParent;
		currentParent.children.push(element);
	}
}
/**
 * 解析文本
 */
function chars(text) {
	text = text.replace(/\s/g, '');
	if (text) {
		currentParent.children.push({
			type: 3,
			text
		})
	}
}
export const parseHTML = (html) => {
	root = "";
	while (html) {
		let textEnd = html.indexOf('<');
		if (textEnd == 0) {
			// 如果当前索引为0，肯定是一个标签 开始标签 结束标签
			let startTagMatch = parseStartTag(); //通过这个方法获取到匹配的结果，targeName,attrs
			if (startTagMatch) {
				start(startTagMatch.tagName, startTagMatch.attrs);
				continue; //如果开始匹配完毕，继续下一次匹配
			}

			// 检测结束标签
			let endTagMatch = html.match(endTag);
			if (endTagMatch) {
				advance(endTagMatch[0].length)
				end(endTagMatch[1])
				continue;
			}
		}
		let text;
		if (textEnd > 0) {
			text = html.substring(0, textEnd)
		}
		if (text) {
			chars(text);
			advance(text.length);
		}
	}
	// 前进，字符串截取
	function advance(n) {
		html = html.substring(n);
	}
	function parseStartTag() {
		let start = html.match(startTagOpen)
		if (start) {
			const match = {
				tagName: start[1],
				attrs: []
			}
			advance(start[0].length) //删除标签
			// 匹配属性
			let end, attr;
			while (!(end = html.match(startTagClose)) && (attr = html.match(attribute))) {
				advance(attr[0].length); //属性去掉
				match.attrs.push({
					name: attr[1],
					value: attr[3] || attr[4] || attr[5]
				})
			}
			// console.log("match:", match)
			// 去掉开始标签的>
			if (end) {
				advance(end[0].length);
				return match;
			}
		}
	}

	return root;
}